interface Point {
    x: number;
    y: number;
}

let p1: Point = {
    x: 100,
    y: 100
}


interface Point2 {
    readonly x: number;
    y: number;
    color?: string;
}

let p2: Point2 = {
    x: 100,
    y: 100,
    color: 'red'
}

// 无法分配到 "x" ，因为它是只读属性。
// p2.x = 200

// interface P3 {
//     // 类型“string | undefined”的属性“color”不能赋给“string”索引类型“number”。ts(2411)
//     color?: string;
//     [key: string]: number;
// }

// 保留Point3的扩展能力
interface Point3 {
    readonly x: number;
    y: number;
    [key: string]: number;
}

let p3: Point3 = {
    x: 1,
    y: 2,
}

p3.good = 3
p3.try = 4

// key的类型可以是number或者string, number需要用下标表示
interface Point4 {
    readonly x: number;
    [key: number]: string;
}

let p4: Point4 = {
    x: 1000
}

p4[0] = 'nice try';
p4[2] = 'nice try2';


// key的值类型必须是下面值类型的父类型
interface Point5 {
    // [key: string]: string; // error：上面key的值类型必须是下面值类型的父类型
    [key: string]: Object;
    [key: number]: number;
}

class Person {
    constructor(public username: string) {

    }
}

class Student extends Person {

}

interface Point6 {
    // [key: string]: string; // error：上面key的值类型必须是下面值类型的父类型
    [key: string]: Person;
    [key: number]: Student;
}